﻿#pragma once


#include <memory>
#include <string>
#include <functional>
#include <mutex>
#include "as_address.h"
#include "as_socket.h"
#include "as_callback.h"

namespace as
{
	namespace net
	{
		class TcpConnection;
		class EpollWatch;
		class Connector;
		class TcpClient
		{
		public:
			typedef std::function<void(TcpClient*)> NetNewConnCbFun;
			TcpClient(std::shared_ptr<EpollWatch> &ep, const Address& serverAddr, 
				const std::string_view &name);
			TcpClient(std::shared_ptr<EpollWatch> &ep, const std::string_view &host, int port, 
				const char* name);;
			virtual ~TcpClient();

			void Start();
			void Stop();
			bool IsStop();

			bool SendMsg(const char* buf, int size);
			bool SendMsg(ByteBuffer& buf);
			bool SendMsg(ByteBufferPtr& buf);

			void Connect();
			void Disconnect();

			TcpClient* SetConnCb(ConnChangeCb fun);
			TcpClient* SetMsgCb(MsgCallback fun);
			TcpClient* SetCloseCb(CloseCallback fun);

			const char* GetName();
			TcpConnectionPtr GetConn();
			int GetConnId();
			bool IsConn() { return connect_; }
			void SetRepeatConnTime(std::time_t ms);
		public:
			void HandleNewConn(socket_fd fd);
			void HandleCloseConn(const TcpConnectionPtr& conn);
			virtual void HandleMsg(TcpConnectionPtr& conn, ByteBufferPtr& buf, int size);
		private:
			std::weak_ptr<EpollWatch> ep_;
			std::unique_ptr<Connector> connector_;
			std::shared_ptr<TcpConnection> connection_;
			std::string svr_name_;
			Address local_addr_;
			ConnChangeCb conn_change_cb_;
			MsgCallback msg_cb_;
			CloseCallback close_cb_;
			bool repeat_ = true;
			bool connect_ = false;
			std::mutex lock_;
			bool is_stop_ = false;
		};







	}
}
